package com.yiku.service.dingding.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkcontact_1_0.models.SearchUserResponse;
import com.aliyun.dingtalkcontact_1_0.models.SearchUserResponseBody;
import com.aliyun.teautil.models.RuntimeOptions;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.taobao.api.ApiException;
import com.yiku.common.*;
import com.yiku.common.dto.dingding.*;
import com.yiku.entity.ReceivementDTO;
import com.yiku.service.U9CloudService;
import com.yiku.service.dingding.DingdingService;
import com.yiku.utils.AccessTokenUtil;
import com.yiku.utils.DdConfigSign;
import com.yiku.utils.LogUtil;
import com.yiku.utils.ServiceResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author ldd
 * @version 1.0
 * @date 2021/4/7 9:05
 */
@Service
public class DingdingServiceImpl implements DingdingService {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    U9CloudService u9CloudService;
    @Override
    public Map<String, String> callBack(JSONObject eventJson) {

        try {

            String processInstanceId = eventJson.getString("processInstanceId");
            String processCode = eventJson.getString("processCode");
            String type = eventJson.getString("type");
            String result = eventJson.getString("result");
            Map<String, Object> formMap = new HashMap<>();
            formMap.put("processInstanceId", processInstanceId);
            if ("finish".equals(type) && "agree".equals(result)) {
                if (DingConstant.PROCESS_CODE.equals(processCode)) {
                    //审批成功
                    logger.info("审批成功");
                     getInstanceDetail(processInstanceId, formMap);
                    u9CloudService.updateU9CTable(formMap);

                }
            } else if ("terminate".equals(type)) {
                //审批撤销

            } else if ("finish".equals(type) && "refuse".equals(result)) {
                    //审批拒绝
                if (DingConstant.PROCESS_CODE.equals(processCode)) {
                    logger.info("审批拒绝");
                }
            }


            return null;
        } catch (Exception e) {
            //失败的情况，应用的开发者应该通过告警感知，并干预修复
            e.printStackTrace();

            return null;
        }
    }
    public Map<String, Object> getInstanceDetail(String processInstanceId, Map<String, Object> formMap) throws ApiException {
        String access_token = getToken().getData();
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/get");
        OapiProcessinstanceGetRequest req = new OapiProcessinstanceGetRequest();
        req.setProcessInstanceId(processInstanceId);
        OapiProcessinstanceGetResponse rsp = client.execute(req, access_token);
//        OapiProcessinstanceGetResponse.ProcessInstanceTopVo processInstance = rsp.getProcessInstance();
        Map<String, Object> map = JSONObject.parseObject(rsp.getBody(), HashMap.class);
        Map<String, Object> processMap = (Map<String, Object>) map.get("process_instance");
        List<Map<String, Object>> formList = (List<Map<String, Object>>) processMap.get("form_component_values");
        for (Map<String, Object> form : formList) {
            formMap.put(form.get("name").toString(), form.get("value") != null ? form.get("value").toString() : null);
        }
        return formMap;
    }

    @Override
    public APIResultDTO<String> getTokenForThird(String corpId, String key, String secret) {
        APIResultDTO<String> apiResultDTO = new APIResultDTO<String>();
        try {
            //第三方的token后续要从数据库获取. 因为每个架构的corpId,key secret都不同
            DefaultDingTalkClient defaultDingTalkClient = new DefaultDingTalkClient(URLConstant.URL_GET_TOKKEN);
            OapiServiceGetCorpTokenRequest tokenRequest = new OapiServiceGetCorpTokenRequest();
            tokenRequest.setAuthCorpid(corpId);
            OapiServiceGetCorpTokenResponse execute = defaultDingTalkClient.execute(tokenRequest, key, secret, "test");
            String body = execute.getBody();
            JSONObject jsonObject = (JSONObject) JSONObject.parse(body);
            String tokenForThird = jsonObject.getString("access_token");
            apiResultDTO.setData(tokenForThird);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return apiResultDTO;
    }

    @Override
    public APIResultDTO<String> getToken() {
        APIResultDTO<String> apiResultDTO = new APIResultDTO<String>();
        try {
            DefaultDingTalkClient client = new DefaultDingTalkClient(URLConstant.URL_GET_INNO_TOKKEN);
            OapiGettokenRequest request = new OapiGettokenRequest();
            request.setAppkey(DingConstant.APPKEY);
            request.setAppsecret(DingConstant.APPSECRET);
            request.setHttpMethod("GET");
            OapiGettokenResponse response = client.execute(request);
            String accessToken = response.getAccessToken();
            apiResultDTO.setData(accessToken);
        } catch (ApiException e) {
            throw new RuntimeException();
        }
        return apiResultDTO;
    }

    //根据业务需求选择对应的token a = 0 自建； a = 1 第三方
    @Override
    public String selectToken() {
        if (DingConstant.APPLICATION_TYPE == 0) {
            return getToken().getData();
        } else {
            return getTokenForThird(DingConstant.CORP_ID, DingConstant.CustomKey, DingConstant.CustomSecret).getData();
        }

    }

    @Override
    public DingdingUserDTO getUserInfoByPhone(Long phone) {
        DingdingUserDTO dingdingUserDTO = new DingdingUserDTO();
        try {
            DingTalkClient client = new DefaultDingTalkClient(URLConstant.GET_BY_MOBILE);
            OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
            req.setMobile(String.valueOf(phone));
            OapiV2UserGetbymobileResponse rsp = client.execute(req, AccessTokenUtil.getToken());
            System.out.println(rsp.getBody());
            JSONObject jsonObject = JSONObject.parseObject(rsp.getBody());

            if (jsonObject.getString("errmsg").equals("ok")) {
                DingTalkClient client1 = new DefaultDingTalkClient(URLConstant.URL_USER_GET);
                OapiV2UserGetRequest req1 = new OapiV2UserGetRequest();
                req1.setUserid(JSONObject.parseObject(jsonObject.getString("result")).getString("userid"));
                OapiV2UserGetResponse rsp1 = client1.execute(req1, AccessTokenUtil.getToken());
//                BeanUtils.copyProperties(rsp1.getResult(), dingdingUserDTO);
                System.out.println(JSONObject.toJSONString(rsp1));
                dingdingUserDTO = JSONObject.parseObject(JSON.toJSONString(rsp1.getResult()), DingdingUserDTO.class);

            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return dingdingUserDTO;
    }

    @Override
    public String getUserIdByName(String name) {
        try {
//            DingTalkClient client = new DefaultDingTalkClient(URLConstant.GET_BY_NAME);
            com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
            config.protocol = "https";
            config.regionId = "central";
            com.aliyun.dingtalkcontact_1_0.Client client = new com.aliyun.dingtalkcontact_1_0.Client(config);
            com.aliyun.dingtalkcontact_1_0.models.SearchUserHeaders searchUserHeaders = new com.aliyun.dingtalkcontact_1_0.models.SearchUserHeaders();
            searchUserHeaders.xAcsDingtalkAccessToken = AccessTokenUtil.getToken();
            com.aliyun.dingtalkcontact_1_0.models.SearchUserRequest searchUserRequest = new com.aliyun.dingtalkcontact_1_0.models.SearchUserRequest()
                    .setQueryWord(name)
                    .setOffset(0)
                    .setSize(10)
                    .setFullMatchField(1);
            SearchUserResponse response = client.searchUserWithOptions(searchUserRequest, searchUserHeaders, new RuntimeOptions());
            SearchUserResponseBody body = response.getBody();


        } catch (ApiException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public OapiV2DepartmentGetResponse.DeptGetResponse getDeptNameByDeptId(Long deptId) {
        OapiV2DepartmentGetResponse.DeptGetResponse result = new OapiV2DepartmentGetResponse.DeptGetResponse();
        try {
            DingTalkClient client = new DefaultDingTalkClient(URLConstant.URL_DEPT_GET);
            OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
            req.setDeptId(deptId);
            OapiV2DepartmentGetResponse rsp = client.execute(req, selectToken());
            result = rsp.getResult();

        } catch (ApiException e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public List<OapiV2DepartmentGetResponse.DeptGetResponse> getSecondDeptList() {
        try {
            DingTalkClient client = new DefaultDingTalkClient(URLConstant.GET_CHILD_DEPT_ID);
            OapiV2DepartmentListsubidRequest req = new OapiV2DepartmentListsubidRequest();
            req.setDeptId(1L);
            OapiV2DepartmentListsubidResponse rsp = client.execute(req, selectToken());
            OapiV2DepartmentListsubidResponse.DeptListSubIdResponse result = rsp.getResult();
            List<Long> deptIdList = result.getDeptIdList();
            ArrayList<OapiV2DepartmentGetResponse.DeptGetResponse> deptGetResponses = new ArrayList<>();
            for (Long aLong : deptIdList) {

                OapiV2DepartmentGetResponse.DeptGetResponse deptId = getDeptNameByDeptId(aLong);
                deptGetResponses.add(deptId);
            }
            return deptGetResponses;
        } catch (ApiException e) {
            e.printStackTrace();
            return null;
        }

    }

    @Override
    public Long getSecondDept(Long deptId) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listparentbydept");
            OapiV2DepartmentListparentbydeptRequest req = new OapiV2DepartmentListparentbydeptRequest();
            req.setDeptId(deptId);
            OapiV2DepartmentListparentbydeptResponse rsp = client.execute(req, selectToken());
            List<Long> parentIdList = rsp.getResult().getParentIdList();
            if (parentIdList != null && parentIdList.size() >= 2) {
                return parentIdList.get(parentIdList.size() - 2);
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public APIResultDTO<String> registerDingding(DingdingReqDTO dingdingReqDTO) {//注册钉钉回调
        //首先获取该组织架构的token
        try {
            String token = selectToken();
            // 重新为企业注册回调
            DefaultDingTalkClient client = new DefaultDingTalkClient(URLConstant.REGISTER_CALLBACK);
            OapiCallBackRegisterCallBackRequest registerRequest = new OapiCallBackRegisterCallBackRequest();
            registerRequest.setUrl(DingConstant.CALLBACK_URL_HOST + "/dingding/callback");
            registerRequest.setAesKey(DingConstant.ENCODING_AES_KEY);
            registerRequest.setToken(DingConstant.TOKEN);
            //事件回调参数
            registerRequest.setCallBackTag(Arrays.asList("bpms_instance_change", "bpms_task_change"));
            //回调接口
            OapiCallBackRegisterCallBackResponse response = client.execute(registerRequest, token);

            //解析回调参数
            DingdingResDTO dingdingResDTO = JSONObject.parseObject(response.getBody(), DingdingResDTO.class);
            //判断两个都正确则为注册成功
            if (FinalDatas.DEFAULT_ZERO == Integer.valueOf(dingdingResDTO.getErrcode()) && FinalDatas.SUCCESS_OK.equalsIgnoreCase(dingdingResDTO.getErrmsg())) {
                LogUtil.info("{}" + dingdingResDTO.getErrmsg(), "钉钉接口注册成功");
            }


        } catch (Exception e) {
            LogUtil.error(e, "钉钉接口注册失败");
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public APIResultDTO<DingdingResDTO> deleteDingdingForRegister(DingdingReqDTO dingdingReqDTO) {
        APIResultDTO<DingdingResDTO> apiResultDTO = new APIResultDTO<DingdingResDTO>();
        try {
            String token = selectToken();
            DingTalkClient deleteClient = new DefaultDingTalkClient(URLConstant.DELETE_CALLBACK);
            OapiCallBackDeleteCallBackRequest request = new OapiCallBackDeleteCallBackRequest();
            request.setHttpMethod("GET");
            OapiCallBackDeleteCallBackResponse rsp = deleteClient.execute(request, token);
//            DingTalkClient deleteClient = new DefaultDingTalkClient(Constant.CALLBACK_URL_HOST + "/call_back/delete_call_back");
//            OapiCallBackDeleteCallBackRequest req = new OapiCallBackDeleteCallBackRequest();
//            req.setHttpMethod("GET");
//            OapiCallBackDeleteCallBackResponse rsp = deleteClient.execute(req, tokenForThird);
            DingdingResDTO dingdingResDTO = JSONObject.parseObject(rsp.getBody(), DingdingResDTO.class);
            //判断两个都正确则为删除成功
            if (FinalDatas.DEFAULT_ZERO == Integer.valueOf(dingdingResDTO.getErrcode()) && FinalDatas.SUCCESS_OK.equalsIgnoreCase(dingdingResDTO.getErrmsg())) {
                LogUtil.info("{}", "钉钉注册接口删除成功");
                apiResultDTO.setData(dingdingResDTO);
            }


        } catch (Exception e) {
            LogUtil.error(e, "钉钉注册接口删除失败");
            e.printStackTrace();
        }
        return apiResultDTO;

    }

    @Override
    public APIResultDTO<DingdingResDTO> deleteDingding(DingdingReqDTO dingdingReqDTO) {
        APIResultDTO<DingdingResDTO> apiResultDTO = new APIResultDTO<DingdingResDTO>();
        try {
            String token = selectToken();
            DingTalkClient deleteClient = new DefaultDingTalkClient(URLConstant.DELETE_CALLBACK);
            OapiCallBackDeleteCallBackRequest request = new OapiCallBackDeleteCallBackRequest();
            request.setHttpMethod("GET");
            OapiCallBackDeleteCallBackResponse rsp = deleteClient.execute(request, token);
            DingdingResDTO dingdingResDTO = JSONObject.parseObject(rsp.getBody(), DingdingResDTO.class);
            //判断两个都正确则为删除成功
            if (FinalDatas.DEFAULT_ZERO == Integer.valueOf(dingdingResDTO.getErrcode()) && FinalDatas.SUCCESS_OK.equalsIgnoreCase(dingdingResDTO.getErrmsg())) {
                LogUtil.info("{}", "钉钉注册接口删除成功");
                apiResultDTO.setData(dingdingResDTO);
            } else {
                System.out.println(JSON.toJSONString(dingdingResDTO));
            }


        } catch (Exception e) {
            LogUtil.error(e, "钉钉注册接口删除失败");
            e.printStackTrace();
        }
        return apiResultDTO;
    }

    @Override
    public APIResultDTO<DingdingResDTO> queryDingdingForRegister(DingdingReqDTO dingdingReqDTO) {
        APIResultDTO<DingdingResDTO> apiResultDTO = new APIResultDTO<DingdingResDTO>();
        try {
            String token = selectToken();
            DingTalkClient client = new DefaultDingTalkClient(URLConstant.QUERY_CALLBACK);
            OapiCallBackGetCallBackRequest req = new OapiCallBackGetCallBackRequest();
            req.setHttpMethod("GET");
            OapiCallBackGetCallBackResponse rsp = client.execute(req, token);
            DingdingResDTO dingdingResDTO = JSONObject.parseObject(rsp.getBody(), DingdingResDTO.class);
            LogUtil.info("钉钉注册回调接口查询成功", rsp.getBody());
            apiResultDTO.setData(dingdingResDTO);

        } catch (Exception e) {
            LogUtil.error(e, "钉钉注册回调接口查询失败");
            e.printStackTrace();
        }
        return apiResultDTO;
    }


    @Override
    public APIResultDTO<DingdingResDTO> getProcessinstance(String processInstanceId, String customkey, DingdingCallBackDTO dingdingCallBackDTO) {

        try {

            String token = selectToken();
            DingTalkClient client = new DefaultDingTalkClient(URLConstant.URL_PROCESSINSTANCE_GET);
            OapiProcessinstanceGetRequest req = new OapiProcessinstanceGetRequest();
            req.setProcessInstanceId(processInstanceId);
            OapiProcessinstanceGetResponse rsp = client.execute(req, token);
            String s = JSON.toJSONString(rsp.getBody());

            DingdingResDTO dingdingResDTO = JSONObject.parseObject(rsp.getBody(), DingdingResDTO.class);
            if (dingdingResDTO.getErrmsg().equals("ok")) {//判断是否是对应组织的审批单。不是直接跳过
                String processInstance = dingdingResDTO.getProcess_instance();
                System.out.println(dingdingCallBackDTO.getType());
                System.out.println("返回的數據" + processInstance);
                DingdingProcessDTO dingdingProcessDTO = JSONObject.parseObject(processInstance, DingdingProcessDTO.class);
                dingdingProcessDTO.setProcessInstanceId(processInstanceId);
                if (null != dingdingProcessDTO) {
                    if ("start".equals(dingdingCallBackDTO.getType())) {

                    }
                    //添加完成进行审核
                    if ("finish".equals(dingdingCallBackDTO.getType())) {
                        //审核通过


                    }
                }
            } else {
                System.out.println("这单子不是我企业的");
            }


        } catch (Exception e) {
            LogUtil.error(e, "根据processInstanceId调用参数异常");
            e.printStackTrace();
        }
        return null;

    }

    @Override
    public APIResultDTO<DingdingProcessDTO> getProcessinstanceHis(String processInstanceId) {
        APIResultDTO<DingdingProcessDTO> re = new APIResultDTO<>();
        try {
            String token = selectToken();
            DingTalkClient client = new DefaultDingTalkClient(URLConstant.URL_PROCESSINSTANCE_GET);
            OapiProcessinstanceGetRequest req = new OapiProcessinstanceGetRequest();
            req.setProcessInstanceId(processInstanceId);
            OapiProcessinstanceGetResponse rsp = client.execute(req, token);
            System.out.println(rsp.getBody());
            DingdingProcessDTO dingdingProcessDTO = JSON.parseObject(JSON.parseObject(rsp.getBody()).getString("process_instance"), DingdingProcessDTO.class);

            re.setData(dingdingProcessDTO);
            return re;

        } catch (Exception e) {
            LogUtil.error(e, "根据processInstanceId调用参数异常");
            e.printStackTrace();
        }
        return re;

    }

    @Override
    public APIResultDTO<String> receivementSubmit(ReceivementDTO req) {
        APIResultDTO<String> resultDTO = new APIResultDTO<>();
        /**
         * 转化ProcessInstanceInputVO
         */
        if (req.getSrcDocType().equals("标准收货")||req.getSrcDocType().equals("委外收货")) {//提交人工号为创建人名称，需要找到对应业务员的编码
            String ywyCodeByCreateByName = u9CloudService.getYwyCodeByCreateByName(req.getTjrgh());
            req.setTjrgh(ywyCodeByCreateByName);
        }
        ProcessInstanceInputVO pro = toProcessInstanceInputVO(req);
        ServiceResult<String> result = startProcessInstance(pro);
        if (result.isSuccess()) {
            resultDTO.setFlag(true);
        }
        resultDTO.setData(result.getResult());
        return resultDTO;
    }

    @Override
    public APIResultDTO<String> updateDingUserIdToU9c() {
        /**
         * 查询出钉钉所有部门及旗下的人员信息
         */
        String token = AccessTokenUtil.getToken();
        List<OapiV2DepartmentListsubResponse.DeptBaseResponse> allDepts = getAllDepts(token, null, null);
        ArrayList<OapiUserListsimpleResponse.ListUserSimpleResponse> personList = new ArrayList<>();
        List<OapiUserListsimpleResponse.ListUserSimpleResponse> userInfoByDept = getUserInfoByDept(token, 1L, null, null);
        System.out.println(JSONObject.toJSONString(userInfoByDept));
        personList.addAll(userInfoByDept);
        for (OapiV2DepartmentListsubResponse.DeptBaseResponse dept : allDepts) {
            System.out.println(dept.getName() + ":::::::::::::");
            userInfoByDept = getUserInfoByDept(token, dept.getDeptId(), null, null);
            System.out.println(JSONObject.toJSONString(userInfoByDept));
            personList.addAll(userInfoByDept);
        }
        System.out.println(allDepts);
        return null;
    }

    private List<OapiV2DepartmentListsubResponse.DeptBaseResponse> getAllDepts(String token, Long deptId, List<OapiV2DepartmentListsubResponse.DeptBaseResponse> list) {
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<OapiV2DepartmentListsubResponse.DeptBaseResponse>();
        }
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
        OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
        if (deptId != null) {

            req.setDeptId(deptId);
        } else {
            req.setDeptId(1L);

        }
        req.setLanguage("zh_CN");
        OapiV2DepartmentListsubResponse rsp = null;
        try {
            rsp = client.execute(req, token);
            List<OapiV2DepartmentListsubResponse.DeptBaseResponse> result = rsp.getResult();
            if (!CollectionUtils.isEmpty(result)) {
                list.addAll(result);
                for (OapiV2DepartmentListsubResponse.DeptBaseResponse deptBaseResponse : result) {
                    getAllDepts(token, deptBaseResponse.getDeptId(), list);
                }
            } else {
                return list;
            }

        } catch (ApiException e) {
            e.printStackTrace();
        }
        return list;
    }

    private List<OapiUserListsimpleResponse.ListUserSimpleResponse> getUserInfoByDept(String token, Long deptId, List<OapiUserListsimpleResponse.ListUserSimpleResponse> list, Long cursor) {
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<OapiUserListsimpleResponse.ListUserSimpleResponse>();
        }
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listsimple");
        OapiUserListsimpleRequest req = new OapiUserListsimpleRequest();
        req.setDeptId(deptId);
        if (cursor == null) {

            req.setCursor(0L);
        } else {
            req.setCursor(cursor);
        }
        req.setSize(100L);
//    req.setOrderField("modify_desc");
        req.setContainAccessLimit(false);
        req.setLanguage("zh_CN");
        OapiUserListsimpleResponse rsp = null;
        try {
            rsp = client.execute(req, token);
            OapiUserListsimpleResponse.PageResult result = rsp.getResult();
            list.addAll(result.getList());
            if (result.getHasMore()) {
                getUserInfoByDept(token, deptId, list, result.getNextCursor());
            } else {
                return list;
            }

        } catch (ApiException e) {
            e.printStackTrace();
        }
        return list;
    }

    private ProcessInstanceInputVO toProcessInstanceInputVO(ReceivementDTO req) {
        ProcessInstanceInputVO result = new ProcessInstanceInputVO();
        result.setOriginatorUserId(req.getTjrgh());
        ArrayList<ProcessInstanceInputVO.TextForm> textForms = new ArrayList<>();

        if (req.getBusinessDate() != null && !req.getBusinessDate().equals("")) {
            ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
            instance.setName("单据日期");
            instance.setValue(req.getBusinessDate());
            textForms.add(instance);
        }
        if (req.getSrcDocType() != null && !req.getSrcDocType().equals("")) {
            ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
            instance.setName("来源类别");
            instance.setValue(req.getSrcDocType());
            textForms.add(instance);
        }
        if (req.getDocNo() != null && !req.getDocNo().equals("")) {
            ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
            instance.setName("单号");
            instance.setValue(req.getDocNo());
            textForms.add(instance);
        }


        if (req.getSupplier() != null && !req.getSupplier().equals("")) {
            ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
            instance.setName("供应商");
            instance.setValue(req.getSupplier());
            textForms.add(instance);
        }

        if (req.getSbDept() != null && !req.getSbDept().equals("")) {
            ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
            instance.setName("申报部门");
            instance.setValue(req.getSbDept());
            textForms.add(instance);
        }
        if (req.getSbr() != null && !req.getSbr().equals("")) {
            ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
            instance.setName("申报人");
            instance.setValue(req.getSbr());
            textForms.add(instance);
        }
        if (!CollectionUtils.isEmpty(req.getDetails())) {
            ArrayList<List<ProcessInstanceInputVO.TextForm>> lists = new ArrayList<>();
            for (ReceivementDTO.Detail detail : req.getDetails()) {
            ArrayList<ProcessInstanceInputVO.TextForm> details = new ArrayList<>();
                if (detail.getId() != null && !detail.getId().equals("")) {
                    ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
                    instance.setName("子表主键");
                    instance.setValue(detail.getId());
                    details.add(instance);
                }
               if (detail.getItemmasterCode() != null && !detail.getItemmasterCode().equals("")) {
                    ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
                    instance.setName("料号");
                    instance.setValue(detail.getItemmasterCode());
                    details.add(instance);
                }

                if (detail.getItemmaster() != null && !detail.getItemmaster().equals("")) {
                    ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
                    instance.setName("品名");
                    instance.setValue(detail.getItemmaster());
                    details.add(instance);
                }
                if (req.getSrcDocType().equals("完工申报")) {
                    if (detail.getMoDocNo() != null && !detail.getMoDocNo().equals("")) {
                        ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
                        instance.setName("生产订单");
                        instance.setValue(detail.getMoDocNo());
                        details.add(instance);
                    }
                    if (detail.getCount() != null && !detail.getCount().equals("")) {
                        ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
                        instance.setName("完工数量");
                        instance.setValue(detail.getCount());
                        details.add(instance);
                    }

                } else {
                    if (detail.getGg() != null && !detail.getGg().equals("")) {

                        ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
                        instance.setName("规格");
                        instance.setValue(detail.getGg());
                        details.add(instance);
                    }
                    if (detail.getStash() != null && !detail.getStash().equals("")) {
                        ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
                        instance.setName("存储地点");
                        instance.setValue(detail.getStash());
                        details.add(instance);
                    }
                    if (detail.getKgy() != null && !detail.getKgy().equals("")) {
                        ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
                        instance.setName("库管员");
                        instance.setValue(detail.getKgy());
                        details .add(instance);
                    }
                    if (detail.getCount() != null && !detail.getCount().equals("")) {
                        ProcessInstanceInputVO.TextForm instance = ProcessInstanceInputVO.TextForm.getInstance();
                        instance.setName("数量");
                        instance.setValue(detail.getCount());
                        details.add(instance);
                    }
                }
                ProcessInstanceInputVO.TextForm instance1 = ProcessInstanceInputVO.TextForm.getInstance();
                instance1.setName("质检情况");
                instance1.setValue("");
                details.add(instance1);
                ProcessInstanceInputVO.TextForm instance2 = ProcessInstanceInputVO.TextForm.getInstance();
                instance2.setName("质检后续处理");
                instance2.setValue("");
                details.add(instance2);
                lists.add(details);


            }

            ProcessInstanceInputVO.DetailForm detailForm = new ProcessInstanceInputVO.DetailForm();
            if (req.getSrcDocType().equals("完工申报")) {
                detailForm.setName("完工申报明细");

            } else {
                detailForm.setName("标准收货、委外收货明细");

            }


            detailForm.setTextForms(lists);
            result.setDetailForms(detailForm);

        }
        result.setTextForms(textForms);
        result.setOriginatorUserId("2442183206685973");
        result.setDeptId(getDeptIdByUserid(2442183206685973L, AccessTokenUtil.getToken()));

        return result;
    }

    private Long getDeptIdByUserid(Long userId, String token) {
        Long deptid = 1L;
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(String.valueOf(userId));
            req.setLanguage("zh_CN");
            OapiV2UserGetResponse rsp = client.execute(req, token);
            OapiV2UserGetResponse.UserGetResponse result = rsp.getResult();
            deptid = result.getDeptIdList().get(0);

            System.out.println(rsp.getBody());
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return deptid;
    }

    //发起审批
    @Override
    public ServiceResult<String> startProcessInstance(ProcessInstanceInputVO processInstance) {
        try {
            DefaultDingTalkClient client = new DefaultDingTalkClient(URLConstant.URL_PROCESSINSTANCE_START);
            OapiProcessinstanceCreateRequest request = new OapiProcessinstanceCreateRequest();
            request.setProcessCode(DingConstant.PROCESS_CODE);

            request.setFormComponentValues(processInstance.generateForms());
            System.out.println(JSON.toJSONString(request));

            /**
             * 如果想复用审批固定流程，使用或签会签的话，可以不传审批人，具体请参考文档： https://open-doc.dingtalk.com/microapp/serverapi2/ebkwx8
             * 本次quickstart，演示不传审批人的场景
             */
//            String approver = null;
//            for (ProcessInstanceInputVO.TextForm textForm : processInstance.getTextForms()) {
//                if(textForm.getName().equals("预警地点")){
//                     approver  = yiKuService.queryApproversByStreet(textForm.getValue());
//                }
//            }
//            //此处根据不同的街道区分不同的审批人
//            if(approver!=null){
//
//            request.setApprovers(approver);
//            }

            request.setOriginatorUserId(processInstance.getOriginatorUserId());
            request.setDeptId(processInstance.getDeptId());
            request.setCcList(processInstance.getOriginatorUserId());
            request.setCcPosition("FINISH");
            String thirdToken = AccessTokenUtil.getToken();
            OapiProcessinstanceCreateResponse response = client.execute(request, thirdToken);
            if (response.getErrcode().longValue() != 0) {
                return ServiceResult.failure(String.valueOf(response.getErrorCode()), response.getErrmsg());

            }
            return ServiceResult.success(response.getProcessInstanceId());

        } catch (Exception e) {
            System.out.println(e);
            LogUtil.error(e, "失败");
            return ServiceResult.failure(ServiceResultCode.SYS_ERROR.getErrCode(), ServiceResultCode.SYS_ERROR.getErrMsg());
        }
    }

    @Override
    public OapiV2UserGetResponse.UserGetResponse getUserInfo(String userId) {
        return getDingUserInfo(userId);
    }

    //根据userId获取用户详情
    private OapiV2UserGetResponse.UserGetResponse getDingUserInfo(String userId) {
        OapiV2UserGetResponse.UserGetResponse result = new OapiV2UserGetResponse.UserGetResponse();
        DingTalkClient client = new DefaultDingTalkClient(URLConstant.URL_USER_GET);
        OapiV2UserGetRequest req = new OapiV2UserGetRequest();
        req.setUserid(userId);
        try {
            OapiV2UserGetResponse rsp = client.execute(req, AccessTokenUtil.getToken());
            result = rsp.getResult();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return result;
    }


    @Override
    public String getJsapiTicket() throws ApiException {
        String token = selectToken();
        DingTalkClient client = new DefaultDingTalkClient(URLConstant.JSAPI_TICKET);
        OapiGetJsapiTicketRequest req = new OapiGetJsapiTicketRequest();
        req.setHttpMethod("GET");
        OapiGetJsapiTicketResponse rsp = client.execute(req, token);
        if (rsp.getBody().contains("\"errmsg\":\"ok\"")) {
            JSONObject json = JSONObject.parseObject(rsp.getBody());
            String ticket = json.getString("ticket");
            System.out.println(rsp.getBody());
            System.out.println(ticket);
            return ticket;
        }
        return null;
    }

    @Override
    public APIResultDTO<JSAPIDTO> getSignature(String jsApiTicket, String url, String timeStamp) {
        APIResultDTO<JSAPIDTO> apiResultDTO = new APIResultDTO<>();
        JSAPIDTO jsapidto = new JSAPIDTO();
        String nonceStr = "fengkuangxiaolushen";
        Long newTimeStamp = Long.valueOf(timeStamp);
        jsapidto.setAgentId(String.valueOf(DingConstant.AGENTID));
        jsapidto.setCorpId(DingConstant.CORP_ID);
        jsapidto.setNonceStr(nonceStr);
        jsapidto.setTimeStamp(newTimeStamp);
        jsapidto.setType("0");
        try {
            String sign = DdConfigSign.sign(jsApiTicket, nonceStr, newTimeStamp, url);
            jsapidto.setSignature(sign);
            apiResultDTO.setData(jsapidto);
            apiResultDTO.setFlag(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return apiResultDTO;
    }

    @Override
    public APIResultDTO<String> getSpaceId(String userId) throws ApiException {
        String token = selectToken();
        APIResultDTO<String> apiResultDTO = new APIResultDTO<>();
        System.out.println("前端返回的用户ID" + userId);
        DingTalkClient client = new DefaultDingTalkClient(URLConstant.CSPACE_INFO);
        OapiProcessinstanceCspaceInfoRequest req = new OapiProcessinstanceCspaceInfoRequest();
        req.setUserId(userId);
        req.setAgentId(DingConstant.AGENTID);
        OapiProcessinstanceCspaceInfoResponse rsp = client.execute(req, token);
        if (rsp.getBody().contains("\"errmsg\":\"ok\"")) {
            JSONObject json = JSONObject.parseObject(rsp.getBody());
            String result = json.getString("result");
            JSONObject jsonObject = JSONObject.parseObject(result);
            String space_id = jsonObject.getString("space_id");
            System.out.println(space_id);
            apiResultDTO.setData(space_id);
            apiResultDTO.setFlag(true);
        }
        return apiResultDTO;
    }


}
